﻿using Newtonsoft.Json;
using SolidEdgeFramework;
using SolidEdgePart;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.Sockets;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using TGComacAddin.command;
using TGCommunity.AddIn;
using static TGComacAddin.TGComacAddin;
using vf_test;
using System.ComponentModel;
using TGSDK;
using TGCommunity;
using SharpGL;
using System.Runtime.InteropServices;

namespace TGComacAddin.View
{
    /// <summary>
    /// TGCreateRosetteView.xaml 的交互逻辑
    /// </summary>
    public partial class TGCreateRosetteView : System.Windows.Window,SolidEdgeFramework.ISEIGLDisplayEvents
    {
        private UInt64 _faceId =UInt64.MaxValue;
        public UInt64 FaceId
        {
            get { return _faceId; }
            set
            {
                _faceId = value;
                if(_faceId!= UInt64.MaxValue && _edgeId!=UInt64.MaxValue && _vertexId!=UInt64.MaxValue)
                {
                    CanPreview = true;
                }
            }
        }

        private UInt64 _edgeId =UInt64.MaxValue;
        public UInt64 EdgeId
        {
            get { return _edgeId; }
            set
            {
                _edgeId = value;
                if (_faceId != UInt64.MaxValue && _edgeId != UInt64.MaxValue && _vertexId != UInt64.MaxValue)
                {
                    CanPreview = true;
                }
            }
        }
        

        private UInt64 _vertexId =UInt64.MaxValue;
        public UInt64 VertexId
        {
            get { return _vertexId; }
            set {
                _vertexId = value;
                if (_faceId != UInt64.MaxValue && _edgeId != UInt64.MaxValue && _vertexId != UInt64.MaxValue)
                {
                    CanPreview = true;
                }
            }
        }

        private UInt64 _rosetteId = UInt64.MaxValue;
        private double _segmentLength = 100;
        public double SegmentLength
        {
            get { return this._segmentLength; }
            set
            {
                if(CanPreview)
                {
                    PreviewChange = true;
                }
                this._segmentLength = value;
                OnPropertyChanged(nameof(SegmentLength));
            }
        }

        bool _canPreview = false;
        public Boolean CanPreview
        {
            get
            {
                return _canPreview;
            }
            set
            {
                if(!_canPreview && value)
                {
                    // 第一次三个ID都齐备
                    PreviewChange = true;
                }
                _canPreview = value;
            }
        }

        bool _previewChange = false;
        public bool PreviewChange
        {
            get { return _previewChange; }
            set
            {
                _previewChange = value;
                OnPropertyChanged(nameof(PreviewChange));
            }
        }

        private int _curStAngIdx = 0;
        public int CurStAngIdx
        {
            get { return _curStAngIdx; }
            set
            {
                _curStAngIdx = value;
                if (CanPreview)
                {
                    PreviewChange = true;
                }
            }
        }

        private int _curDirAngIdx = 0;
        public int CurDirAngIdx
        {
            get { return _curDirAngIdx; }
            set
            {
                _curDirAngIdx = value;
                if (CanPreview)
                {
                    PreviewChange = true;
                }
            }
        }

        private int _curHandIdx = 0;
        public int CurHandIdx
        {
            get { return _curHandIdx; }
            set
            {
                _curHandIdx = value;
                if (CanPreview)
                { 
                    PreviewChange = true;
                }
            }
        }
        public event PropertyChangedEventHandler PropertyChanged;

        protected virtual void OnPropertyChanged(string propertyName)
        {
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
        }

        SolidEdgeFramework.Application SEAPP = TGC_Constants.SEAPP;

        public TGCreateRosetteView()
        {
            InitializeComponent();

            // 使出现在屏幕中间
            this.WindowStartupLocation = WindowStartupLocation.CenterScreen;
            this.DataContext = this;
            PropertyChanged += PopertyChanged;
            Topmost = true;
        }
        private  List<double> _coordPoints = new List<double>();
        private ConnectionPointController _connectController = null;
        private void PopertyChanged(object sender, PropertyChangedEventArgs e)
        {
            if (e.PropertyName == nameof(PreviewChange))
            {
                try
                {
                    // 需要生新生成预览时
                    SEAPP.AbortCommand(true);
                    Command cmd = SEAPP.CreateCommand(SolidEdgeConstants.seCmdFlag.seNoDeactivate);
                    SolidEdgeFramework.ISEMouseEx mouse = cmd.Mouse as SolidEdgeFramework.ISEMouseEx;
                    if (_connectController == null)
                    {
                        _connectController = new ConnectionPointController(this);

                    }

                    // 先解绑事件
                    SolidEdgeFramework.Window window = SEAPP.ActiveWindow as SolidEdgeFramework.Window;
                    if(_connectController != null)
                    {
                        _connectController.UnadviseAllSinks();
                    }

                    // 重新计算各坐标线
                    double startAngle = _curStAngIdx == 0 ? 0 : -45;
                    double dirAngle = _curDirAngIdx == 0 ? 0 : 90;
                    bool isRightHand = _curHandIdx == 0;
                    VFAdapter.vfStartLinkWithCAD(2);
                    VfHRESULT status = VFAdapter.CalcRosetteSegments(out int ptSize, out IntPtr pPts, _faceId, _vertexId, _edgeId, startAngle, dirAngle, SegmentLength, isRightHand);
                    if (status == VfHRESULT.vf_Success)
                    {
                        // 绑定事件
                        _connectController.AdviseSink<SolidEdgeFramework.ISEIGLDisplayEvents>(window.View.GLDisplayEvents);

                        _coordPoints.Clear();
                        unsafe
                        {
                            double* pDbValue = (double*)pPts;
                            for (int i = 0; i < ptSize; i++)
                            {
                                _coordPoints.Add(pDbValue[i * 3]);
                                _coordPoints.Add(pDbValue[i * 3 + 1]);
                                _coordPoints.Add(pDbValue[i * 3 + 2]);
                            }
                        }
                        Marshal.FreeHGlobal(pPts);

                        // 更新视图
                        window.View.Update();
                    }
                }
                catch(Exception ex)
                {

                }
              
            }
        }

        private void btnSelFace_Click(object sender, RoutedEventArgs e)
        {
            // 选择参照面
            PartDocument partDoc = SEAPP.GetActiveDocument() as PartDocument;
            SEAPP.AbortCommand(true);
            Command cmd = SEAPP.CreateCommand(SolidEdgeConstants.seCmdFlag.seNoDeactivate);
            command.TGSelect selSingleCmd = new command.TGSelect(cmd.Mouse, cmd, partDoc, "请选择参照面", (int)GeomType.vf_face, true);
            cmd.Start();

            Task.Run(() =>
            {
                while (selSingleCmd.Status == SelectStatus.Running)
                {
                    System.Threading.Thread.Sleep(100);
                }
                if (selSingleCmd.Status == SelectStatus.Success)
                {
                    FaceId = selSingleCmd.ElementIds[0].Id;
                    this.Dispatcher.Invoke(new Action(() =>
                    {
                        labelFace.Content = FaceId.ToString();
                    }));
                }
            });
        }

        private void btnSelPoint_Click(object sender, RoutedEventArgs e)
        {
            // 选择参照原点
            PartDocument partDoc = SEAPP.GetActiveDocument() as PartDocument;
            SEAPP.AbortCommand(true);
            Command cmd = SEAPP.CreateCommand(SolidEdgeConstants.seCmdFlag.seNoDeactivate);
            command.TGSelect selSingleCmd = new command.TGSelect(cmd.Mouse, cmd, partDoc, "请选择参照原点", (int)GeomType.vf_vertex, true);
            cmd.Start();

            Task.Run(() =>
            {
                while (selSingleCmd.Status == SelectStatus.Running)
                {
                    System.Threading.Thread.Sleep(100);
                }
                if (selSingleCmd.Status == SelectStatus.Success)
                {
                    VertexId = selSingleCmd.ElementIds[0].Id;
                    this.Dispatcher.Invoke(new Action(() =>
                    {
                        labelPoint.Content = VertexId.ToString();
                    }));                 

                }
            });
        }

        private void btnSelEdge_Click(object sender, RoutedEventArgs e)
        {
            // 选择参照方向线
            PartDocument partDoc = SEAPP.GetActiveDocument() as PartDocument;
            SEAPP.AbortCommand(true);

            Command cmd = SEAPP.CreateCommand(SolidEdgeConstants.seCmdFlag.seNoDeactivate);
            command.TGSelect selSingleCmd = new command.TGSelect(cmd.Mouse, cmd, partDoc, "请选择参照边", (int)GeomType.vf_curve, true);
            cmd.Start();

            Task.Run(() =>
            {
                while (selSingleCmd.Status == SelectStatus.Running)
                {
                    System.Threading.Thread.Sleep(100);
                }
                if (selSingleCmd.Status == SelectStatus.Success)
                {
                    EdgeId = selSingleCmd.ElementIds[0].Id;
                    this.Dispatcher.Invoke(new Action(() =>
                    {
                        labelDir.Content = EdgeId.ToString();

                    }));
                }
            });

        }

        private void OKButton_Click(object sender, RoutedEventArgs e)
        {
            // 创建六条线坐标系
            if (FaceId == UInt64.MaxValue || VertexId == UInt64.MaxValue || EdgeId == UInt64.MaxValue)
            {
                MessageBox.Show("请选定参照原点、边、面");
                return;
            }
                    
            try
            {
                double stAng = double.Parse((cbStAng.SelectedValue as ComboBoxItem).Content.ToString());
                double dirAng = double.Parse((cbDirAng.SelectedValue as ComboBoxItem).Content.ToString());
                string handRule = cbHandRule.SelectedIndex == 0 ? "Right" : "Left";
                string faceIdStr = FaceId.ToString();
                string vertexIdStr = VertexId.ToString();
                string edgeIdStr = EdgeId.ToString();
                VFAdapter.vfStartLinkWithCAD(2);
                VfHRESULT status = VFAdapter.vfCreateRosette(faceIdStr,vertexIdStr,edgeIdStr, stAng, dirAng, SegmentLength,
    handRule,out string rosetteId, out string line1, out string line2, out string line3, out string line4,out string line5, out string line6);
                if (status == VfHRESULT.vf_Success)
                {
                    SEAPP.StatusBar = rosetteId;
                    _connectController.UnadviseAllSinks();
                    Close();
                }else
                {

                }
            }
            catch (Exception ex)
            {

            }

        }

        private void CancelButton_Click(object sender, RoutedEventArgs e)
        {
            // 关闭窗口
            if(_connectController != null)
            {
                _connectController.UnadviseAllSinks();
            }
            this.Close();
        }

        void ISEIGLDisplayEvents.BeginDisplay()
        {

        }

        void ISEIGLDisplayEvents.EndDisplay()
        {
        
        }

        void ISEIGLDisplayEvents.BeginIGLMainDisplay(object pUnknownIGL)
        {
            if (!CanPreview)
                return;
            if(_coordPoints==null || _coordPoints.Count==0)
                return;
            try
            {
                IGL gl = pUnknownIGL as IGL;
                gl.glColor3f(0.0f, 1.0f, 0.0f);
                gl.glLineWidth(4.0f);
                gl.glBegin(SharpGL.OpenGL.GL_LINES);

                int ptSize = _coordPoints.Count / 3;
                for (int pointIdx = 0; pointIdx < ptSize; pointIdx++)
                {
                    gl.glVertex3d((float)_coordPoints[pointIdx * 3], (float)_coordPoints[pointIdx * 3 + 1], (float)_coordPoints[pointIdx * 3 + 2]);
                }
                gl.glEnd();
            }
            catch (Exception ex)
            {

            }
          
        }

        void ISEIGLDisplayEvents.EndIGLMainDisplay(object pUnknownIGL)
        {
            
        }
    }
}
